package com.example.kangjujiaofei.utils;

import org.apache.commons.codec.digest.DigestUtils;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import sun.misc.BASE64Encoder;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.*;

public class StringUtils {
    public static String getAsciiSort(Map<String, Object> map) {
        String result = "";
        List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(map.entrySet());
        // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
        Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
            public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                return ((String) o1.getKey()).compareToIgnoreCase((String) o2.getKey());
            }
        });


        // 构造签名键值对的格式
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> item : infoIds) {
            if (item.getKey() != null || item.getKey() != "") {
                String key = item.getKey();
                Object val = item.getValue();
                if (!(val == "" || val == null)) {
                    sb.append(key + "=" + val + "&");
                }
            }
        }
        result = sb.toString();
        return result;
    }


    /**
     * Description:MD5工具生成token
     * @param value
     * @return
     */
    public static String getMD5Value(String value){
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] md5ValueByteArray = messageDigest.digest(value.getBytes());
            BigInteger bigInteger = new BigInteger(1 , md5ValueByteArray);
            return bigInteger.toString(32).toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 通用加密方法
     * @param str     需要加密的字符串
     * @param isUpper 字母大小写(false为小写，true为大写)
     * @param bit     加密的位数（16,32,64）
     * @return
     */
    public static String getMD5(String str, boolean isUpper, Integer bit) {
        String md5 = null;
        try {
            // 创建加密对象
            MessageDigest md = MessageDigest.getInstance("md5");
            if (bit == 64) {
                BASE64Encoder bw = new BASE64Encoder();
                md5 = bw.encode(md.digest(str.getBytes("utf-8")));
            } else {
                // 计算MD5函数
                md.update(str.getBytes());
                byte b[] = md.digest();
                int i;
                StringBuilder sb = new StringBuilder();
                for (byte aB : b) {
                    i = aB;
                    if (i < 0) {
                        i += 256;
                    }
                    if (i < 16) {
                        sb.append("0");
                    }
                    sb.append(Integer.toHexString(i));
                }
                md5 = sb.toString();
                if (bit == 16) {
                    //截取32位md5为16位
                    md5 = md5.substring(8, 24);
                    if (isUpper) {
                        md5 = md5.toUpperCase();
                    }
                    return md5;
                }
            }
            //转换成大写
            if (isUpper) {
                md5 = md5.toUpperCase();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return md5;
    }

    /**

     * MD5方法

     * @param text 明文

     * @param key 密钥

     * @return 密文

     * @throws Exception

     */

    public static String md5(String text, String key) throws Exception {
//加密后的字符串

        String encodeStr= DigestUtils.md5Hex(text + key);

        System.out.println("MD5加密后的字符串为:encodeStr="+encodeStr);

        return encodeStr;

    }

    /**
     * 将map转为xml-string
     *
     * @param map
     * @return
     */
    public static String mapToXml(Map map) {
        StringBuilder sb = new StringBuilder();
        try {
            sb.append("<xml>");
            Set<String> keys = map.keySet();
            for (String key : keys) {
                sb.append("<"+key+">"+String.valueOf(map.get(key))+"</"+key+">");
            }
            sb.append("</xml>");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }



    /**
     * XML格式字符串转换为Map
     *
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
//            WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
            throw ex;
        }

    }
}
